import 'dart:async';

import 'package:hockey/jzx_apps.dart';
import 'package:hockey/jzx_models.dart';
import 'package:hockey/services/jzx_user.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';

class JzxCoinsController extends GetxController {
  var items = <JzxGoodsData>[].obs;

  var order = const JzxOrderData();

  late InAppPurchase _inAppPurchase;
  late StreamSubscription<List<PurchaseDetails>> _subscription;
  Completer<bool>? _completer;

  @override
  onInit() {
    _inAppPurchase = InAppPurchase.instance;

    super.onInit();

    JzxLogPvManger.tracking(page: JzxLogPages.purchase);

    fetchData();
    _subscription = _inAppPurchase.purchaseStream.listen(
        (List<PurchaseDetails> purchaseDetailsList) {
      _listenToPurchaseUpdated(purchaseDetailsList);
    }, onDone: () {
      _subscription.cancel();
    }, onError: (error) {
      // handle error here.
    });
  }

  fetchData() async {
    showLoading();
    final params = {
      'isIncludeSubscription': false,
      'payChannel': 'IAP',
    };
    items.value = await JzxNetRepository.client.goodsList(params);
    hideLoading();
  }

  /// 下单
  serverPayment(JzxGoodsData item) async {
    // if (kDebugMode) {
    //   // 直接刷新用户数据
    //   JzxUserService.to.user.value = JzxUserService.to.user.value.copyWith(
    //      availableCoins: item.exchangeCoin,
    //   );
    //   return;
    // }

    JzxLogPvManger.tracking(page: JzxLogPages.createorder);

    try {
      showLoading();
      final params = {
        'entry': '',
        'source': '',
        'payChannel': 'IAP',
        'goodsCode': item.code,
      };
      order = await JzxNetRepository.client.createOrder(params);
      final res = await applePaymet(order.goodsCode, order.orderNo);
      if (res == true) {
        // JzxUserService.to.user.value = JzxUserService.to.user.value.copyWith(
        //   availableCoins: item.exchangeCoin,
        // );
        JzxUserService.to.updateUser();
      }

      hideLoading();
    } catch (e) {
      // print(e);
    }
  }

  /// 发起支付
  /// lanlintestpurchase1225@ll.com
  /// LanLinTest0825P
  Future<bool?> applePaymet(String productId, String orderNo) async {
    // _orderNo = orderNo;

    // 如果是iOS设备进行设置代理，接口苹果服务器的回调。
    if (GetPlatform.isIOS) {
      final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
          _inAppPurchase
              .getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
      await iosPlatformAddition.setDelegate(ExamplePaymentQueueDelegate());
    }

    // 查询后台返回的ProductId是否在苹果服务器上注册了
    final ProductDetailsResponse productDetailResponse =
        await _inAppPurchase.queryProductDetails({productId});

    // 查询不到说明没注册
    if (productDetailResponse.error != null) {
      showMessage('Failed to obtain internal purchase information.');
      return false;
    }

    // 查询不到商品详情说明没注册
    if (productDetailResponse.productDetails.isEmpty) {
      showMessage('Unfurnished goods');
      return false;
    }

    _completer = Completer();

    // 发起支付
    PurchaseParam purchaseParam = PurchaseParam(
        productDetails: productDetailResponse.productDetails.first,

        /// 添加自己服务器上生成的订单
        applicationUserName: orderNo);

    /// 向苹果服务器发起支付请求
    await _inAppPurchase.buyConsumable(purchaseParam: purchaseParam);
    // print(res);
    return _completer?.future;
  }

  void _listenToPurchaseUpdated(
      List<PurchaseDetails> purchaseDetailsList) async {
    for (var purchaseDetails in purchaseDetailsList) {
      // print(purchaseDetails.status);

      if (purchaseDetails.status == PurchaseStatus.pending) {
        /// 等待购买中
        showLoading(message: 'Payment...');
      } else if (purchaseDetails.status == PurchaseStatus.canceled) {
        /// 取消订单
        _inAppPurchase.completePurchase(purchaseDetails);
        showMessage('Cancel');
      } else {
        if (purchaseDetails.status == PurchaseStatus.error) {
          /// 购买出错
          showMessage('Error: ${purchaseDetails.error}');
          _inAppPurchase.completePurchase(purchaseDetails);
        } else if (purchaseDetails.status == PurchaseStatus.purchased ||
            purchaseDetails.status == PurchaseStatus.restored) {
          /// 调用后台接口,发放商品
          // deliverProduct(purchaseDetails);
          // NetRepository.client.iOSPaymentVerify(orderNo, payload, productId, transactionId)
          final state = await _orderVerfiy(purchaseDetails);
          _completer?.complete(state);
          if (state) {
            showMessage('Successfully purchased');
          } else {
            showMessage('Verfiy order failed');
          }
        }

        if (purchaseDetails.pendingCompletePurchase) {
          await _inAppPurchase.completePurchase(purchaseDetails);
        }
      }
    }
  }

  /// 订单校验
  Future<bool> _orderVerfiy(PurchaseDetails details) async {
    try {
      showLoading(message: 'Verifying...');

      var params = {
        'payload': details.verificationData.serverVerificationData,
        'orderNo': order.orderNo,
        'transactionId': details.purchaseID,
        'type': 1,
      };
      // Get.dialog(AlertDialog(
      //   title: Text('验单参数'),
      //   content: Text('$params'),
      // ));
      final res = await JzxNetRepository.client.verifyPayment(params);
      // Get.dialog(AlertDialog(
      //   title: Text('验单结果'),
      //   content: Text('$res'),
      // ));
      return res;
    } catch (e) {
      showMessage('$e');
      return false;
    }
  }
}

/// Example implementation of the
/// [`SKPaymentQueueDelegate`](https://developer.apple.com/documentation/storekit/skpaymentqueuedelegate?language=objc).
///
/// The payment queue delegate can be implementated to provide information
/// needed to complete transactions.
class ExamplePaymentQueueDelegate implements SKPaymentQueueDelegateWrapper {
  @override
  bool shouldContinueTransaction(
      SKPaymentTransactionWrapper transaction, SKStorefrontWrapper storefront) {
    return true;
  }

  @override
  bool shouldShowPriceConsent() {
    return false;
  }
}
